#include <tcpbridgenet.hxx>
#include <tcpclientsocket.hxx>

#include <bridgemessage.hxx>
#include "bridgeconn.hxx"
#include <myfilelog.hxx>
#include <loghelper.hxx>
#include <vector>
#include <utility.hxx>
#include <macro.hxx>
#include <iostream>

using namespace std;

	BridgeConn::BridgeConn(const string& host, tUInt32 port, FileLog* filelog)
: Thread(),
	_host(host),
	_port(port),
	_in_que(),
	_out_que(),
	_shutdown_requested(false),
	_filelog(filelog)
{
	Start();
}
BridgeConn::~BridgeConn()
{
}

void BridgeConn::Shutdown(void)
{
	_shutdown_requested = true;
}

void BridgeConn::SendMsg(tBridgeMsg* bmsg)
{
	_out_que.Push(bmsg);
}

void BridgeConn::Execute(Thread::Arg)
{
	TcpClientSocket* remote = new TcpClientSocket();
	TcpBridgeNet* bridgenet = new TcpBridgeNet(remote, _filelog);

	APPENDMSGEX("BridgeConn started..", 0);

	BridgeNet::tBridgeNetStatus status;
	tBridgeMsg* bmsg = NULL;

	while (!_shutdown_requested)
	{
		if (!remote->IsConnected())
		{
			APPENDMSGEX("Connecting Bridge "<<_host<<":"<<_port<<"...", 3);

			if (0 != remote->Connect(_host, _port))
			{
				APPENDMSGEX("Connecting Failed to Bridge "<<_host<<":"<<_port, 2);

				Thread::Sleep(6);
				continue;
			}
			else
			{
				APPENDMSGEX("Connecting successfully to Bridge "<<_host<<":"<<_port, 0);
			}
		}

		if (bridgenet->IsReadyForRead(100) > 0)
		{
			status = bridgenet->ReceiveMsg(&bmsg);
			switch (status)
			{
			case TcpBridgeNet::eMsgAvailable:
				_in_que.Push(bmsg);
				break;
			default:
				{
					APPENDMSGEX("Received unexpected msg with status #"<<status<<" from Bridge!!", 2);

		//			delete remote;
		//			delete bridgenet;
//
//					remote = new TcpClientSocket();
//					bridgenet = new TcpBridgeNet(remote, _filelog);

					break;
				}
			}
		}

		if ((bridgenet->IsReadyForWrite() > 0) && (bmsg = _out_que.Pop()))
		{
			if (bmsg)
			{
				if (bridgenet->SendMsg(bmsg))
					APPENDMSGEXDBG("Message sent successfully", 0);
				else
					APPENDMSGEX("Message sending failed!", 2);

				ReleaseBMsg(bmsg);
			}
		}

		Thread::Yield();
	}

	delete remote;
	delete bridgenet;

	APPENDMSGEX("BridgeConn shutdowned.", 0);
}
tBridgeMsg* BridgeConn::GetMsg(void)
{
    return _in_que.Pop();
}
